<template>
  <div
    contenteditable
    ref="chatCollection"
    id="chatCollection"
    class="chatCollection"
    @input="onInput"
    @paste="onPaste"
    :class="[disabled ? 'read-only' : '']"
  ></div>
</template>
<script>
export default {
  model: {
    prop: "message",
    event: "sendMessage",
  },
  props: {
    message: {
      type: String,
      default: "",
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    characters: {
      type: Array,
      default: () => ["@"],
    },
  },
  computed: {
    content: {
      get() {
        return this.message;
      },
      set(value) {
        this.$emit("sendMessage", value);
        this.$emit("change", value);
      },
    },
  },
  data() {
    return {
      _chatEl: null, // 当前可以边元素的载体 contenteditable
      cursorIndex: 0, // 光标位置
      oldContent: "", // 记录旧的内容用来比对新的内容
    };
  },
  methods: {
    // 过滤输入框中复制过来的文本
    onPaste(e) {
      e.stopPropagation();
      e.preventDefault();
      let text = "",
        event = e.originalEvent || e;
      if (event.clipboardData && event.clipboardData.getData) {
        text = event.clipboardData.getData("text/plain");
      } else if (window.clipboardData && window.clipboardData.getData) {
        text = window.clipboardData.getData("Text");
      }
      if (document.queryCommandSupported("insertText")) {
        document.execCommand("insertText", false, text);
      } else {
        document.execCommand("paste", false, text);
      }
    },
    // 用户输入
    onInput() {
      let innerHTML = this._chatEl.innerHTML;
      const oldArr = this.oldContent.split("");
      const newArr = innerHTML.split("");
      let contentStr = innerHTML;
      // 使用旧的内容将新的内容值替换为空  留下的将是输入的内容
      oldArr.forEach((str) => {
        contentStr = contentStr.replace(str, "");
      });
      // 当剩余的为 特殊字符时
      if (this.characters.includes(contentStr)) {
        // 比对算法,找出当前光标的位置,找到当前输入的位置
        newArr.some((now, index) => {
          if (
            innerHTML.substring(0, index) !==
            this.oldContent.substring(0, index)
          ) {
            this.cursorIndex = index;
            return true;
          }
          this.cursorIndex = 0;
        });
        this.$emit("handlerCharacter", contentStr);
      }
      this.content = innerHTML;
      this.oldContent = innerHTML;
    },
    // 选择@的人
    checkPerson(data) {
      const span = `<span contenteditable="false" data-type="@" data-name="${data.name}" data-personid="${data.personId}"  style="color:#4A90E2;">@${data.name}</span>&nbsp;`;
      let html = this._chatEl.innerHTML;
      // 光标位置为0在后面追加,不为0从中间替换
      if (this.cursorIndex) {
        html =
          html.substr(0, this.cursorIndex - 1) +
          span +
          html.substr(this.cursorIndex, html.length);
      } else {
        html = html.substr(0, html.length - 1) + span;
      }
      console.log(html);
      this._chatEl.innerHTML = html;
      this.content = this._chatEl.innerHTML;
      this.oldContent = this._chatEl.innerHTML;
      this.keepLastIndex();
    },
    keepLastIndex(obj = this._chatEl) {
      // 在微信小程序等没有window和dom的环境下无法使用
      if (window.getSelection) {
        //ie11 10 9 ff safari
        obj.focus(); //解决ff不获取焦点无法定位问题
        var range = window.getSelection(); //创建range
        range.selectAllChildren(obj); //range 选择obj下所有子内容
        range.collapseToEnd(); //光标移至最后
      } else if (document.selection) {
        //ie10 9 8 7 6 5
        var range = document.selection.createRange(); //创建选择对象
        //var range = document.body.createTextRange();
        range.moveToElementText(obj); //range定位到obj
        range.collapse(false); //光标移至最后
        range.select();
      } else {
        throw new Error("当前环境无法操作光标位置");
      }
    },
    // 获取提交数据
    getModel() {
      return {
        _el: this._chatEl,
        content: this._chatEl.innerHTML,
        text: this._chatEl.innerText,
        needData: this.queryUserList(this._chatEl.children),
      };
    },
    // 获取特殊dom元素上存放的信息
    queryUserList(domList) {
      if (!domList.length) return [];
      let needList = [];
      let filterData = (arr) => {
        arr = Array.from(arr);
        arr.forEach((item) => {
          if (item.dataset.name && item.dataset.personid) {
            needList.push({
              name: item.dataset.name,
              personid: item.dataset.personid,
            });
          }
          if (item.children.length) {
            filterData(item.children);
          }
        });
      };
      filterData(domList);
      return needList;
    },
    getTextMemberPoint() {
      var contentInput = document.getElementById("content-input");
      let contentInputPosition = contentInput.getBoundingClientRect(); //
      var xStart = 30;
      var yStart = 30;
      let contentInputW = contentInput.clientWidth - 60; // 60 两边的padding
      let msg = handleMessage(contentInput);
      var emojiW = 24;
      var emojis = this.emojis;
      for (var i = 0; i < emojis.length; i++) {
        msg = msg.replace(emojis[i].reg, "#!#");
      }
      let msgArr = msg.split("#!#");
      let emojiCount = msgArr.length - 1;
      msg = msgArr.join("");
      // 计算距离
      let textOffsetX = getTextWidth(msg, "14px Micrsofot Yahei");

      let emojiOffsetX = emojiCount * emojiW;
      let offX = (textOffsetX + emojiOffsetX + 14) % contentInputW;
      let count = Math.floor((textOffsetX + emojiOffsetX + 14) / contentInputW);
      if (count > 3) count = 3;
      let offY = count * 26; // 8是上面padding

      return {
        x: contentInputPosition.x + xStart + offX,
        y: contentInputPosition.y + yStart + offY,
      };
      // 插入光标
      contentInput.focus();
      var selection = getSelection();
      var range = selection.getRangeAt(0);
      var textNode = range.startContainer;
      // 获取光标位置
      var rangeStartOffset = range.startOffset;
      range.setStart(
        textNode,
        rangeStartOffset + handleMessage(contentInput).length
      );
      range.collapse(true);
      selection.removeAllRanges();
      selection.addRange(range);
    },
  },
  mounted() {
    // 获取元素
    this._chatEl = this.$refs.chatCollection;
    // 初始化赋值
    this._chatEl.innerHTML = this.content;
    this.oldContent = this.content;
  },
};
</script>

<style lang="scss" scoped>
.chatCollection {
  width: 100%;
  outline: none;
  min-height: 100px;
  max-height: 100%;
  height: auto !important;
  overflow-y: auto;
  border-radius: 4px;
  border: 1px solid #999;
  padding: 5px;
  box-sizing: border-box;
  //   内容可读写，过滤粘贴内容中的样式，图片
  &.read-write-plaintext-only {
    -webkit-user-modify: read-write-plaintext-only;
  }
  //   正常编辑，不会过滤粘贴内容中的样式，图片
  &.read-write {
    -webkit-user-modify: read-write;
  }
  //   只读状态
  &.read-only {
    -webkit-user-modify: read-only;
    cursor: not-allowed;
  }
  &:empty:before {
    content: "请输入";
    color: #333;
  }
  &:focus:before {
    content: none;
  }
}
</style>